# pragma once
#include <iostream>
#include <math.h>
#include <chrono>

class timer_funcal
{
public:
    timer_funcal(const char* funcName)
    {
        _funcname = funcName;
        start = std::chrono::high_resolution_clock::now();
    }

    ~timer_funcal()
    {
        finish = std::chrono::high_resolution_clock::now();
        _elapsed = std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count();
        printf("Function name: %s. Elapsed : %f us\n", _funcname ,_elapsed);
    }  

private:
    std::chrono::high_resolution_clock::time_point start;
    std::chrono::high_resolution_clock::time_point finish;
    double        _elapsed;
    const char*   _funcname;
};

#define PROFILE_THIS_IMPL(funcname)    timer_funcal CONCAT(_timer, __LINE__)(funcname)
#define PROFILE_THIS() PROFILE_THIS_IMPL(__FUNCTION__)
#define CONCAT_IMPL(x, y)  x##y
#define CONCAT(x, y) CONCAT_IMPL(x, y)